<?php
/**
 * Created by PhpStorm.
 * User: lufficc
 * Date: 2016/8/25
 * Time: 13:07
 */

namespace App\Repositories;

use App\Contracts\TestingCache;
use Closure;
use DB;

abstract class Repository
{
    /**
     * @var TestingCache
     */
    private $testingCache;

    public abstract function model();

    public abstract function tag();

    private function getTestingCache()
    {
        if ($this->testingCache == null) {
            $this->testingCache = app('TestingCache');
            $this->testingCache->setTag($this->tag());
            $this->testingCache->setTime($this->cacheTime());
        }
        return $this->testingCache;
    }

    /**
     * 批量更新数据
     */
    public function batchUpdate($tableName = "", $multipleData = array()){
        if(count($multipleData) > 0 ) {
            // column or fields to update
            $updateColumn = array_keys($multipleData[0]);
            $referenceColumn = $updateColumn[0]; //e.g id
            unset($updateColumn[0]);
            $whereIn = "";

            $sql = "UPDATE ".$tableName." SET ";
            foreach ( $updateColumn as $uColumn ) {
                $sql .=  $uColumn." = CASE ";

                foreach( $multipleData as $data ) {
                    $sql .= "WHEN ".$referenceColumn." = ".$data[$referenceColumn]." THEN '".$data[$uColumn]."' ";
                }
                $sql .= "ELSE ".$uColumn." END, ";
            }
            foreach( $multipleData as $data ) {
                $whereIn .= "'".$data[$referenceColumn]."', ";
            }
            $sql = rtrim($sql, ", ")." WHERE ".$referenceColumn." IN (".  rtrim($whereIn, ', ').")";
            // Update
            return DB::update(DB::raw($sql));

        } else {
            return false;
        }

    }

    public function cacheTime()
    {
        return 60;
    }

    public function count()
    {
        $count = $this->remember($this->tag() . '.count', function () {
            return $this->model()->count();
        });
        return $count;
    }

    public function all()
    {
        $all = $this->remember($this->tag() . '.all', function () {
            return $this->model()->all();
        });
        return $all;
    }

    public function remember($key, Closure $entity, $tag = null)
    {
        return $this->getTestingCache()->remember($key, $entity, $tag);
    }

    public function forget($key, $tag = null)
    {
        $this->getTestingCache()->forget($key, $tag);
    }

    public function clearCache($tag = null)
    {
        $this->getTestingCache()->clearCache($tag);
    }

    public function clearAllCache()
    {
        $this->getTestingCache()->clearAllCache();
    }

}